package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qingcheng.dao.*;
import com.qingcheng.entity.PageResult;
import com.qingcheng.pojo.order.*;
import com.qingcheng.service.goods.SkuService;
import com.qingcheng.service.order.CartService;
import com.qingcheng.service.order.OrderService;
import com.qingcheng.util.IdWorker;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service(interfaceClass = OrderService.class)
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private OrderLogMapper orderLogMapper;

    @Autowired
    private OrderConfigMapper orderConfigMapper;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private OrderStatisticsMapper orderStatisticsMapper;

    /**
     * 返回全部记录
     *
     * @return
     */
    @Override
    public List<Order> findAll() {
        return orderMapper.selectAll();
    }

    /**
     * 分页查询
     *
     * @param page 页码
     * @param size 每页记录数
     * @return 分页结果
     */
    @Override
    public PageResult<Order> findPage(int page, int size) {
        PageHelper.startPage(page, size);
        Page<Order> orders = (Page<Order>) orderMapper.selectAll();
        return new PageResult<Order>(orders.getTotal(), orders.getResult());
    }

    /**
     * 条件查询
     *
     * @param searchMap 查询条件
     * @return
     */
    @Override
    public List<Order> findList(Map<String, Object> searchMap) {
        Example example = createExample(searchMap);
        return orderMapper.selectByExample(example);
    }

    /**
     * 分页+条件查询
     *
     * @param searchMap
     * @param page
     * @param size
     * @return
     */
    @Override
    public PageResult<Order> findPage(Map<String, Object> searchMap, int page, int size) {
        PageHelper.startPage(page, size);
        Example example = createExample(searchMap);
        Page<Order> orders = (Page<Order>) orderMapper.selectByExample(example);
        return new PageResult<Order>(orders.getTotal(), orders.getResult());
    }

    /**
     * 根据Id查询
     *
     * @param id
     * @return
     */
    @Override
    public Order findById(String id) {
        return orderMapper.selectByPrimaryKey(id);
    }


    @Autowired
    private CartService cartService;

    @Reference
    private SkuService skuService;


    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 新增
     *
     * @param order
     */
    @Override
    public Map<String, Object> add(Order order) {
        //获取购物车（刷新单价）
        List<Map<String, Object>> newOrderItemList = cartService.findNewOrderItemList(order.getUsername());

        //获取选中的购物车
        List<OrderItem> orderItems = newOrderItemList.stream()
                .filter(cart -> (Boolean) cart.get("checked"))
                .map(cart -> (OrderItem)cart.get("item"))
                .collect(Collectors.toList());

        //扣减库存
        if(!skuService.deductionStock(orderItems)){
            throw new RuntimeException("库存扣减失败");
        }

        try {
            //保存订单主表
            order.setId(idWorker.nextId()+"");
            //Stream流操作统计数据
            IntStream numStream = orderItems.stream().mapToInt(OrderItem::getNum);
            IntStream moneyStream = orderItems.stream().mapToInt(OrderItem::getMoney);

            //此流只能使用一次，一次后自动关闭
            int sumN = numStream.sum();
            int sumM = moneyStream.sum();
            order.setTotalNum(sumN);
            order.setTotalMoney(sumM);
            int preferential = cartService.preferential(order.getUsername());
            order.setPreMoney(preferential);
            order.setPayMoney(sumM-preferential);
            order.setCreateTime(new Date());
            order.setOrderStatus("0");
            order.setPayStatus("0");
            order.setConsignStatus("0");
            orderMapper.insert(order);

            //保存订单明细表
                //均分优惠
            double proportion = (double)order.getPayMoney()/sumM;
            for(OrderItem orderItem:orderItems){
                orderItem.setOrderId(order.getId());
                orderItem.setId(idWorker.nextId()+"");
                orderItem.setPayMoney( (int)(orderItem.getMoney()* proportion) );
                orderItemMapper.insert(orderItem);
            }
            int i = 1/0;
        } catch (Exception e) {
            e.printStackTrace();
            //发送回滚消息
            rabbitTemplate.convertAndSend("","queue.skuback", JSON.toJSONString(orderItems));
            //抛出异常，让其回滚！
            throw new RuntimeException("订单生成失败");
        }

        //清除选中的购物车
        cartService.deleteCheckedCart(order.getUsername());

        //返回订单号和支付金额
        HashMap<String, Object> map = new HashMap<>();
        map.put("ordersn", order.getId() );
        map.put("money",order.getPayMoney());
        return map;
    }

    /**
     * 修改
     *
     * @param order
     */
    @Override
    public void update(Order order) {
        orderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     * 删除
     *
     * @param id
     */
    @Override
    public void delete(String id) {
        orderMapper.deleteByPrimaryKey(id);
    }

    @Override
    public OrderAndItems findOrderAndItemsById(String id) {
        Order order = orderMapper.selectByPrimaryKey(id);
        Example example = new Example(OrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId", id);
        List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
        return new OrderAndItems(order, orderItems);
    }

    @Override
    public List<Order> unConsign(String consignStatus, int[] ids) {
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("consignStatus", "0");
        criteria.andIn("id", Arrays.asList(ids));
        return orderMapper.selectByExample(example);
    }

    @Override
    public void batchSend(List<Order> orders) {
        //判断运单号和物流公司是否为空
        if (Objects.isNull(orders) || orders.size() == 0) {
            throw new RuntimeException("订单为空");
        }
        for (Order order : orders) {
            if (Objects.isNull(order.getShippingName())
                    && Objects.isNull(order.getShippingCode())) {
                throw new RuntimeException("运单号或物流公司为空");
            }
//            if ("0".equals(order.getPayStatus())){
//                //前端校验
//                throw new RuntimeException("尚未付款");
//            }
        }
        OrderLog orderLog = new OrderLog();
        Date date = new Date();
        for (Order order : orders) {
            order.setOrderStatus("3");//订单状态  已发货
            order.setConsignStatus("2"); //发货状态  已发货
            order.setConsignTime(date);//发货时间
            orderMapper.updateByPrimaryKeySelective(order);
            //即时日志
            //TODO
            orderLog.setOperater("ss");
            orderLog.setOperateTime(date);
            orderLog.setOrderId(Long.getLong(order.getId()));
            orderLog.setOrderStatus("3");
            orderLog.setPayStatus(order.getPayStatus());
            orderLog.setConsignStatus("2");
        }
    }

    /**
     * 定时查询超时订单并处理
     */
    @Override
    public void orderTimeOutLogic() {
        OrderConfig orderConfig = orderConfigMapper.selectByPrimaryKey(1);
        Integer orderTimeout = orderConfig.getOrderTimeout();
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        LocalDateTime localDateTime = LocalDateTime.now().minusMinutes(orderTimeout);
        //超时比较
        criteria.andLessThan("createTime", localDateTime);
        criteria.andEqualTo("orderStatus", "0");
        criteria.andEqualTo("isDelete", "0");
        List<Order> orders = orderMapper.selectByExample(example);
        for (Order order : orders) {
            //记录订单变动日志
            OrderLog orderLog = new OrderLog();
            orderLog.setId(idWorker.nextId() + "");
            orderLog.setOperater("system");// 系统
            orderLog.setOperateTime(new Date());//当前日期
            orderLog.setOrderStatus("4");
            orderLog.setPayStatus(order.getPayStatus());
            orderLog.setConsignStatus(order.getConsignStatus());
            orderLog.setRemarks("超时订单，系统自动关闭");
            orderLog.setOrderId(Long.getLong(order.getId()));
            orderLogMapper.insert(orderLog);
            //更改订单状态
            order.setOrderStatus("4");
            order.setCloseTime(new Date());//关闭日期
            orderMapper.updateByPrimaryKeySelective(order);
        }
    }

    /**
     * 合并订单
     *
     * @param id1
     * @param id2
     */
    @Override
    public void mergeOrder(String id1, String id2) {
        //判断订单是否合法
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderStatus", '0');
        criteria.andEqualTo("isDelete", '0');
        criteria.andEqualTo("id", id1);
        Order order1 = orderMapper.selectByPrimaryKey(example);
        if (Objects.isNull(order1)) {
            throw new RuntimeException("订单为空");
        }
        System.out.println(order1);
        criteria.andEqualTo("id", id2);
        Order order2 = orderMapper.selectByPrimaryKey(example);
        if (Objects.isNull(order2)) {
            throw new RuntimeException("订单为空");
        }
        System.out.println(order2);
        //合并订单
        //1、数量合计

        //金额合计、优惠金额、邮费、实付金额、订单更新时间、买家留言、订单来源
        order1.setTotalMoney(order1.getTotalMoney() + order2.getTotalMoney());

        //订单明细（可能合并）

    }

    /**
     * 统计订单
     */
    @Override
    @Transactional
    public void orderCount() {
        System.out.println("orderCount运行serviceIMPL");
        OrderStatistics orderStatistics = new OrderStatistics();
        orderStatistics.setId(idWorker.nextId() + "");
        //1、浏览人数
        orderStatistics.setPrderplars(1000);
        //昨天
//        LocalDate date = LocalDate.now().minusDays(1);
        String date = "2019-03-14";
        String date1 = "2019-03-15";
        //今天
//        LocalDate date1 = LocalDate.now().minusDays(0);

        //3、订单数 昨天的产生所有订单
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andBetween("createTime", date, date1);
        List<Order> orders = orderMapper.selectByExample(example);
        orderStatistics.setOrderdds(orders.size());

        //5、有效订单数（）
        criteria.andNotEqualTo("isDelete", "1");
        List<Order> orders2 = orderMapper.selectByExample(example);
        orderStatistics.setOrderyxdds(orders2.size());

        //2、下单人数(默认为次)
        Integer xdrs = orderMapper.selectOrderxdrs(date, date1);
//        Integer xdrs = orders.size();
        orderStatistics.setOrderxdrs(xdrs);
        List<Order> orders3 = orderMapper.selectOrderfkrs(date, date1);
        //8、付款人数
        orderStatistics.setOrderfkrs(orders3.size());


        //9、付的付款订单数 已支订单（未删除）
        criteria.andEqualTo("payStatus", "1");
        List<Order> orders1 = orderMapper.selectByExample(example);
        orderStatistics.setOrderfkdds(orders1.size());

        //4、下单件数，6、下单金额(金额合计)，7、退款金额 10、已支付件数,11支付金额
        int count = 0;
        int money = 0;
        int returnMoney = 0;
        int orderReady = 0;
        int moneyReady = 0;
        for (Order order : orders) {
            //6、下单金额(金额合计)
            money += order.getTotalMoney();
            //支付金额
            moneyReady += order.getPayMoney();
            //7、退款金额
            returnMoney += order.getTotalMoney();
            Example example1 = new Example(OrderItem.class);
            Example.Criteria criteria1 = example1.createCriteria();
            criteria1.andEqualTo("orderId", order.getId());
            List<OrderItem> orderItems = orderItemMapper.selectByExample(example1);
            for (OrderItem orderItem : orderItems) {
                //4、下单件数
                count += orderItem.getNum();
                if ("1".equals(order.getPayStatus())) {
                    //10、已支付件数
                    orderReady += orderItem.getNum();

                }
            }
        }
        orderStatistics.setOrderxdjs(count);
        orderStatistics.setOrderxdje(money);
        orderStatistics.setOrdertkje(returnMoney);
        orderStatistics.setOrderfkjs(orderReady);
        orderStatistics.setOrderfkje(moneyReady);
        if (orderReady != 0) {
            orderStatistics.setOrderkdj(moneyReady / orderReady);
        } else {
            orderStatistics.setOrderkdj(0);
        }
        orderStatisticsMapper.insert(orderStatistics);
        System.out.println("orderCount运行serviceIMPL+++完");
    }

    @Override
    public void test00() {
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderStatus", "1");
        Integer orders = orderMapper.selectCountByExample(example);
        criteria.andEqualTo("payStatus", "1");
        Integer orders2 = orderMapper.selectCountByExample(example);
        System.out.println(orders);
        System.out.println(orders2);
    }


    /**
     * 构建查询条件
     *
     * @param searchMap
     * @return
     */
    private Example createExample(Map<String, Object> searchMap) {
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        if (searchMap != null) {
            // 订单id
            if (searchMap.get("id") != null && !"".equals(searchMap.get("id"))) {
                criteria.andLike("id", "%" + searchMap.get("id") + "%");
            }
            // 支付类型，1、在线支付、0 货到付款
            if (searchMap.get("payType") != null && !"".equals(searchMap.get("payType"))) {
                criteria.andLike("payType", "%" + searchMap.get("payType") + "%");
            }
            // 物流名称
            if (searchMap.get("shippingName") != null && !"".equals(searchMap.get("shippingName"))) {
                criteria.andLike("shippingName", "%" + searchMap.get("shippingName") + "%");
            }
            // 物流单号
            if (searchMap.get("shippingCode") != null && !"".equals(searchMap.get("shippingCode"))) {
                criteria.andLike("shippingCode", "%" + searchMap.get("shippingCode") + "%");
            }
            // 用户名称
            if (searchMap.get("username") != null && !"".equals(searchMap.get("username"))) {
                criteria.andLike("username", "%" + searchMap.get("username") + "%");
            }
            // 买家留言
            if (searchMap.get("buyerMessage") != null && !"".equals(searchMap.get("buyerMessage"))) {
                criteria.andLike("buyerMessage", "%" + searchMap.get("buyerMessage") + "%");
            }
            // 是否评价
            if (searchMap.get("buyerRate") != null && !"".equals(searchMap.get("buyerRate"))) {
                criteria.andLike("buyerRate", "%" + searchMap.get("buyerRate") + "%");
            }
            // 收货人
            if (searchMap.get("receiverContact") != null && !"".equals(searchMap.get("receiverContact"))) {
                criteria.andLike("receiverContact", "%" + searchMap.get("receiverContact") + "%");
            }
            // 收货人手机
            if (searchMap.get("receiverMobile") != null && !"".equals(searchMap.get("receiverMobile"))) {
                criteria.andLike("receiverMobile", "%" + searchMap.get("receiverMobile") + "%");
            }
            // 收货人地址
            if (searchMap.get("receiverAddress") != null && !"".equals(searchMap.get("receiverAddress"))) {
                criteria.andLike("receiverAddress", "%" + searchMap.get("receiverAddress") + "%");
            }
            // 订单来源：1:web，2：app，3：微信公众号，4：微信小程序  5 H5手机页面
            if (searchMap.get("sourceType") != null && !"".equals(searchMap.get("sourceType"))) {
                criteria.andLike("sourceType", "%" + searchMap.get("sourceType") + "%");
            }
            // 交易流水号
            if (searchMap.get("transactionId") != null && !"".equals(searchMap.get("transactionId"))) {
                criteria.andLike("transactionId", "%" + searchMap.get("transactionId") + "%");
            }
            // 订单状态
            if (searchMap.get("orderStatus") != null && !"".equals(searchMap.get("orderStatus"))) {
                criteria.andLike("orderStatus", "%" + searchMap.get("orderStatus") + "%");
            }
            // 支付状态
            if (searchMap.get("payStatus") != null && !"".equals(searchMap.get("payStatus"))) {
                criteria.andLike("payStatus", "%" + searchMap.get("payStatus") + "%");
            }
            // 发货状态
            if (searchMap.get("consignStatus") != null && !"".equals(searchMap.get("consignStatus"))) {
                criteria.andLike("consignStatus", "%" + searchMap.get("consignStatus") + "%");
            }
            // 是否删除
            if (searchMap.get("isDelete") != null && !"".equals(searchMap.get("isDelete"))) {
                criteria.andLike("isDelete", "%" + searchMap.get("isDelete") + "%");
            }

            // 数量合计
            if (searchMap.get("totalNum") != null) {
                criteria.andEqualTo("totalNum", searchMap.get("totalNum"));
            }
            // 金额合计
            if (searchMap.get("totalMoney") != null) {
                criteria.andEqualTo("totalMoney", searchMap.get("totalMoney"));
            }
            // 优惠金额
            if (searchMap.get("preMoney") != null) {
                criteria.andEqualTo("preMoney", searchMap.get("preMoney"));
            }
            // 邮费
            if (searchMap.get("postFee") != null) {
                criteria.andEqualTo("postFee", searchMap.get("postFee"));
            }
            // 实付金额
            if (searchMap.get("payMoney") != null) {
                criteria.andEqualTo("payMoney", searchMap.get("payMoney"));
            }

        }
        return example;
    }

}
